<?php

class DB_Shard_Stats extends DB_Shard {

    public $db = array();

    public $shardKey;

    public $options;

    public $table;

    public function __construct($options, $shardKey) {

        $this->options = $options;
        $this->shardKey = $shardKey;

        $this->shard($options['config'], $shardKey);
    }

    /**
     * shard
     * 分片处理
     *
     * @param  array $shards
     * @param  array $shardKey
     * @return void
     */
    public function shard($shards, $shardKey) {

        $dbId = $shardKey[$shards['key']] % $shards['modules'];

        try {

            $pageOption = array('start' => 0, 'perPage' => 1);
            $confService =& Service::factory('Stats_Service_DbConf');
            $rows = $confService->listTableConf($dbId, $this->options['table'], $shardKey['start_date'], null, $pageOption);
            $db = $rows[0];
            if (!$db) {
                throw new Yaf_Exception('shard data not found');
            }

            $databasePre = array_shift(explode('_', $this->options['table']));

            $master = array('host' => $db['dcMasterIp'], 'port' => $db['dcMasterPort']);
            $slave =  array('host' => $db['dcSlaveIp'], 'port' => $db['dcSlavePort']);

            $dbs = array($master, $slave);
            if (!$shardKey['host_type']) {
                shuffle($dbs);
            } elseif ($shardKey['host_type'] == 'slave') {
                $dbs = array($slave, $master);
            }

            $this->db['dsn'] = sprintf('mysql:dbname=%s_%03d;host=%s;port=%d',
                                       $databasePre, $dbId, $dbs[0]['host'], $dbs[0]['port']);
            $this->db['user'] = $shards['user'];
            $this->db['password'] = $shards['password'];
            $this->db['charset'] = $shards['charset'];
            $this->db['persistent'] = $shards['persistent'];
            $this->db['failover'] = sprintf('mysql:dbname=%s_%03d;host=%s;port=%d',
                                       $databasePre, $dbId, $dbs[1]['host'], $dbs[1]['port']);

        } catch (Exception $e) {
            throw new Yaf_Exception($e);
        }

    }

    /**
     * getRandomByDiId
     * 根据站点ID和时间间隔生成随机数
     *
     * @param integer $diId 站点ID
     * @param integer $second 控制平均多长时间进行一次随机操作，单位(s)
     * @return integer
     */
    protected function _getRandomByDiId($diId = 0, $second = 3600) {

        $timestamp = time();
        // 通过站点ID、以及时间来生成一个随机数种子
        $seed = floor($timestamp / $second) + $diId;
        /*
        $md5 = md5($seed);
        // 把 md5 值的字串每一位转成 10 进制数，并求和，其结果作为随机数
        $random = 0;
        for($i = 0; $i < 32; $i ++) {
            $random = $random + hexdec($md5{$i});
        }
         */
        return sprintf('%u', crc32($seed));
    }

    /**
     * getDB
     * 获取数据库配置
     *
     * @return void
     */
    public function getDB() {

        $db = array('dsn' => $this->db['dsn'],
                    'user' => $this->db['user'],
                    'password' => $this->db['password'],
                    'charset' => $this->db['charset'],
                    'persistent' => $this->db['persistent'],
                    'failover' => $this->db['failover']
                    );

        return $db;
    }

}
